#include <stdlib.h>
#include <vector>
#include <cmath>
#include "utils.h"

using namespace std;

// =====================================================
//           Vector3D:
//           A vector in 3-dimensional space
// =====================================================

Vector3D::Vector3D()
{
}

Vector3D::Vector3D(double x, double y, double z)
{
	this->x = x;
	this->y = y;
	this->z = z;
}

Vector3D::~Vector3D()
{
}

double Vector3D::length()
{
	return sqrt(pow(this->x, 2) + pow(this->y, 2) + pow(this->z, 2));
}

// =====================================================
//           Point3D:
//           A point in 3-dimensional space
// =====================================================

Point3D::Point3D()
{
    this->isMidpoint = false;
    this->vertex = NULL;

	this->x = 0;
	this->y = 0;
	this->z = 0;
}

Point3D::Point3D(double x, double y, double z)
{
    this->isMidpoint = false;
    this->vertex = NULL;

	this->x = x;
	this->y = y;
	this->z = z;
}

Point3D::~Point3D()
{
}

Point3D Point3D::operator*(const double& scalar)
{
	Point3D result(this->x * scalar, 
                   this->y * scalar, 
                   this->z * scalar);
    return result;
}

Point3D Point3D::operator+(const Point3D& param)
{
	Point3D result(this->x + param.x, 
                   this->y + param.y, 
                   this->z + param.z);

    return result;
}

// =====================================================
//        BSplineSnapshot:
//        A snapshot of the geometry used to 
//        find the point on the curve at u.
// =====================================================

BSplineSnapshot::BSplineSnapshot()
{
    lines = new vector<Line3D*>();
}

BSplineSnapshot::~BSplineSnapshot()
{
}

void BSplineSnapshot::setU(double u)
{
	this->u = u;
}

void BSplineSnapshot::initializeSpace(int numElements)
{
	int i; // counter
	for (i = 0; i < numElements; i++)
	{
		this->lines->push_back(new Line3D());
	}
}

void BSplineSnapshot::initFromPoints(const std::vector<Point3D>& points)
{
	int i; // counter
	Line3D* newLine;
	
	for (i = 0; i < points.size() - 1; i++)
	{
		newLine = new Line3D();
		newLine->start = new Point3D(points[i].x, points[i].y, points[i].z);
		newLine->end = new Point3D(points[i+1].x, points[i+1].y, points[i+1].z);
		this->lines->push_back(newLine);
	}
}

